# -*- coding: utf-8 -*-
#使用__iter__()方法获取iterator对象，使用next()方法进行遍历，当到达最后一个元素之后，如果还执行next()方法则触发StopIteration异常
#可迭代对象iterable
#可迭代对象必须满足以下两个条件
#1、实现了__iter__()方法
#2、__iter__()方法返回了迭代器对象
#3、可迭代对象与迭代对象的区别为是否具有next()方法，可迭代对象没有这个方法
#凡是可用于for循环的都是可迭代对象，凡是可用于next()方法的都是迭代器
def iterator_method():
    li = [1,2,3,4,5,6]
    iterator = iter(li)
    try:
        while True:
            print(next(iterator))
    except StopIteration:
        print('end')

#自定义可迭代对象
class MyIterable:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        """返回一个新的迭代器实例"""
        return MyIterator(self.data)

#自定义可迭代对象的迭代器
class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < len(self.data):
            result = self.data[self.index]
            self.index += 1
            return result
        else:
            raise StopIteration #抛出异常

#定义一个生成器函数
def generator_demo(n):
    li2=[]
    a = 0
    while a < n:
        li2.append(a)
        yield a
        a+=1
    print(li2)



if __name__ == '__main__':
    iterator_method()
    # 使用for循环遍历可迭代对象
    my_iterable = MyIterable([1, 2, 3, 4])
    for item in my_iterable:
        print(item)
    #获取迭代器并使用next()遍历
    iter_obj = iter(my_iterable)
    print(next(iter_obj))
    # 生成器：一边遍历一边计算的机制，叫做生成器
    #列表推导表达式
    li = [i * 5 for i in range(10)]
    print(li)
    #生成器，可使用next()方法遍历
    gen = (i * 5 for i in range(10))
    print(gen)
    print(next(gen))
    #生成器函数，使用了yield关键字的函数就是生成器函数
    #yield的作用
    #1、类似return，将指定值或者多个值返回给调用者
    #2、yield语句一次返回一个结果，在每个结果中间，挂起函数，执行next()函数，再重新从挂起点再继续往下执行，类似中断
    gen2 = generator_demo(10)
    for item in gen2:
        print(item)